﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MbUnit.Framework;
using Gallio.Framework.Assertions;

namespace Frost
{
    public static class UnitAssertions {

        //Numeric
        public static T ShouldBe<T>(this T actual, T expected) {
            Assert.AreEqual<T>(expected, actual);
            return actual;
        }

        public static T ShouldBeGreaterThan<T>(this T actual, T expected) {
            Assert.GreaterThan<T>(actual, expected);
            return actual;
        }

        //Boolean
        public static bool ShouldBeFalse(this bool actual) {
            Assert.IsFalse(actual);
            return actual;
        }

        public static bool ShouldbeTrue(this bool actual) {
            Assert.IsTrue(actual);
            return actual;
        }

        //References
        public static object ShouldNotBeNull(this object actual) {
            Assert.IsNotNull(actual);
            return actual;
        }

        public static object ShouldBeTypeOf<T>(this object actual) {
            Assert.IsInstanceOfType(typeof(T), actual);
            return actual;
        }

        //Strings
        public static string ShouldNotBeEmpty(this string actual) {
            Assert.IsFalse(string.IsNullOrEmpty(actual), "I was expecting a string with values but found nothing.");
            return actual;
        }

        public static string ShouldBeEmpty(this string actual) {
            Assert.IsTrue(string.IsNullOrEmpty(actual), "I was expecting to find either null or empty string but instead I found {0}", actual);
            return actual;
        }
        
        // Collections
        public static IEnumerable<T> ShouldNotBeEmpty<T>(this IEnumerable<T> actual) {
            Assert.IsNotEmpty(actual);
            return actual;
        }

        public static IEnumerable<T> ShouldBeEmpty<T>(this IEnumerable<T> actual) {
            Assert.IsEmpty(actual);
            return actual;
        }

        public static IEnumerable<T> ShouldContain<T>(this IEnumerable<T> actual, T expected) {
            Assert.Contains(actual, expected);
            return actual;
        }

        public static IEnumerable<T> ShouldContain<T>(this IEnumerable<T> actual, Func<T, bool> search) {
            var result = actual.Where(search);
            if (result.Count() == 0)
                throw new AssertionException("No elements matching predicate were found.");
            return actual;
        }

    }
}
